<?php
/**
 * ----------------------------------------
 * @link http://www.ruaby.com/
 * @copyright Copyright (c) 2016 RuabySoft
 * @license http://www.ruaby.com/license/
 *
 * @author 18/8/2 下午11:07
 */
namespace Zeke\Io\Socket;

use Exception;
use Zeke\Zee\Event\IoEvent;
use Zeke\Zee\Event\EventEmitter;
use Zeke\Contracts\Io\Loop\LoopContract;
use Zeke\Io\Socket\TcpAdapter\TcpServer;
use Zeke\Io\Socket\UnixAdapter\UnixServer;
use Zeke\Contracts\Io\Socket\ServerContract;
use Zeke\Io\Socket\SecureAdapter\SecureServer;
use Zeke\Contracts\Io\Socket\ConnectionContract;


class Server extends EventEmitter implements ServerContract
{

    /**
     * @var ServerContract $serverAdapter
     */
    private $serverAdapter;


    /**
     * Server constructor.
     * @param $uri
     * @param LoopContract $loop
     * @param array $context
     */
    public function __construct($uri, LoopContract $loop, $context = array())
    {
        // sanitize TCP context options if not properly wrapped
        if ($context && (!isset($context['tcp']) && !isset($context['tls']) && !isset($context['unix']))) {
            $context = array('tcp' => $context);
        }

        // apply default options if not explicitly given
        $context += array(
            'tcp'   => array(),
            'tls'   => array(),
            'unix'  => array()
        );

        $scheme = 'tcp';
        $pos    = strpos($uri, '://');
        if ($pos !== false) {
            $scheme = substr($uri, 0, $pos);
        }

        //设置serverAdapter
        $this->setServerAdapter($scheme,$uri,$loop,$context);


        //注册server监听事件
        $this->_registerEvent($this);

    }


    /**
     * 设置 serverAdapter
     *
     * @param $scheme
     * @param $uri
     * @param $loop
     * @param $context
     *
     *
     * @author <liu.bin@ruaby.com> 2018-08-10 22:22
     */
    private function setServerAdapter($scheme,$uri,$loop,$context)
    {
        if ($scheme === 'unix') {
            $this->serverAdapter = new UnixServer($uri, $loop, $context['unix']);
        } else {
            $tcpServer = new TcpServer(str_replace('tls://', '', $uri), $loop, $context['tcp']);

            if ($scheme === 'tls') {
                $this->serverAdapter = new SecureServer($tcpServer, $loop, $context['tls']);
            }else{
                $this->serverAdapter = $tcpServer;
            }
        }
    }



    /**
     * 注册监听事件
     * @param Server $sender
     * @author liu.bin 2018/8/10 16:42
     */
    private function _registerEvent($sender)
    {

        //添加connect事件 处理函数
        $this->serverAdapter->on(IoEvent::CONNECT, function (ConnectionContract $conn) use ($sender) {
            $sender->emit(IoEvent::CONNECT, array($conn));
        });


        //添加error事件 处理函数
        $this->serverAdapter->on(IoEvent::ERROR, function (Exception $error) use ($sender) {
            $sender->emit(IoEvent::ERROR, array($error));
        });
    }


    /**
     * 获取当前地址
     *
     * @return null|string
     * @author liu.bin 2018/8/10 16:38
     */
    public function getAddress()
    {
        return $this->serverAdapter->getAddress();
    }


    /**
     *暂停
     *
     * @author liu.bin 2018/8/10 16:38
     */
    public function pause()
    {
        $this->serverAdapter->pause();
    }


    /**
     *
     * 初始化
     *
     * @author liu.bin 2018/8/10 17:13
     */
    public function resume()
    {
        $this->serverAdapter->resume();
    }


    /**
     * 关闭
     *
     * @author liu.bin 2018/8/10 17:28
     */
    public function close()
    {
        $this->serverAdapter->close();
    }

}